package com.feature50.clarity.css;

import com.feature50.clarity.decorator.FormDecorator;
import com.feature50.clarity.Form;
import com.feature50.clarity.ResourceLoader;
import com.feature50.clarity.ClarityConstants;
import com.feature50.util.ArrayUtils;
import com.feature50.util.StringUtils;
import com.feature50.util.SwingUtils;
import com.steadystate.css.parser.CSSOMParser;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.awt.Component;

import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.apache.log4j.Logger;

import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.SwingUtilities;

public class CSSFormDecorator implements FormDecorator {
    private static final Logger logger = Logger.getLogger(CSSFormDecorator.class);

    public void decorate(Form form, List<JComponent> allComponents) {
        String[] cssNames = form.getStylesheetNames();
        if (ArrayUtils.isNullOrEmpty(cssNames)) return;

        for (int i = 0; i < cssNames.length; i++) {
            String cssName = cssNames[i];
            if (cssName.endsWith(".css")) cssName = cssName.substring(0, cssName.length() - 4);
            InputStream in = ResourceLoader.getInstance().getInputStream(ResourceLoader.Type.Stylesheet, cssName, "css");
            if (in == null) {
                logger.warn(String.format("Stylesheet '%1$s' not found", cssName));
                continue;
            }

            CSSOMParser parser = new CSSOMParser();
            InputSource is = new InputSource(new InputStreamReader(in));
            CSSStyleSheet stylesheet = null;
            try {
                stylesheet = parser.parseStyleSheet(is);
            } catch (IOException e) {
                logger.warn(String.format("Couldn't load stylesheet '%1$s'", cssName), e);
                continue;
            }

            CSSRuleList list = stylesheet.getCssRules();
            for (int k = 0; k < list.getLength(); k++) {
                CSSStyleRule rule = (CSSStyleRule) list.item(k);

                String selector = rule.getSelectorText();
                JComponent[] components = SwingUtils.parseSelector(selector, allComponents);

                CSSStyleDeclaration style = rule.getStyle();
                for (int j = 0; j < style.getLength(); j++) {
                    boolean result = CSSPropertyHandlers.getInstance().handle(components, style.item(j), style.getPropertyValue(style.item(j)));
                    if (!result) {
                        logger.warn(String.format("CSS property '%1$s' in selector '%2$s' not supported", style.item(j), selector));
                    }
                }
            }

        }
    }
}
